Skip to content

Commit

Permalink
Decompose SymbolHelper into dedicated extension classes (#9229)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-mikula-sonarsource committed May 2, 2024
1 parent c755a17 commit ca0f118
Show file tree
Hide file tree
Showing 32 changed files with 3,199 additions and 3,179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static bool IsKnownType(this AttributeSyntax attribute, ImmutableArray<Kn

public static bool IsKnownType(this AttributeSyntax attribute, KnownType knownType, SemanticModel semanticModel) =>
attribute.Name.GetName().Contains(GetShortNameWithoutAttributeSuffix(knownType))
&& SymbolHelper.IsKnownType(attribute, knownType, semanticModel);
&& ((SyntaxNode)attribute).IsKnownType(knownType, semanticModel);

private static string GetShortNameWithoutAttributeSuffix(KnownType knownType) =>
knownType.TypeName == nameof(Attribute)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.Extensions
namespace SonarAnalyzer.Extensions;

internal static class ObjectCreationExpressionSyntaxExtensions
{
internal static class ObjectCreationExpressionSyntaxExtensions
{
public static bool IsKnownType(this ObjectCreationExpressionSyntax objectCreation, KnownType knownType, SemanticModel semanticModel) =>
objectCreation.Type.GetName().EndsWith(knownType.TypeName)
&& SymbolHelper.IsKnownType(objectCreation, knownType, semanticModel);
public static bool IsKnownType(this ObjectCreationExpressionSyntax objectCreation, KnownType knownType, SemanticModel semanticModel) =>
objectCreation.Type.GetName().EndsWith(knownType.TypeName)
&& ((SyntaxNode)objectCreation).IsKnownType(knownType, semanticModel);

public static SyntaxToken? GetObjectCreationTypeIdentifier(this ObjectCreationExpressionSyntax objectCreation) =>
objectCreation?.Type.GetIdentifier();
}
public static SyntaxToken? GetObjectCreationTypeIdentifier(this ObjectCreationExpressionSyntax objectCreation) =>
objectCreation?.Type.GetIdentifier();
}
595 changes: 0 additions & 595 deletions analyzers/src/SonarAnalyzer.CSharp/Extensions/SyntaxNodeExtensions.cs

This file was deleted.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ public List<SecondaryLocation> GetIssueLocations(TypeDeclarationSyntax typeDecla
+ $"'{typeSymbol.Name}' or mark the type as 'sealed'.");
}

var destructor = FindMethodImplementationOrAbstractDeclaration(typeSymbol, SymbolHelper.IsDestructor, typeDeclarationSyntax)
.OfType<DestructorDeclarationSyntax>()
.FirstOrDefault();
var destructor = FindMethodImplementationOrAbstractDeclaration(typeSymbol, x => x.IsDestructor(), typeDeclarationSyntax)
.OfType<DestructorDeclarationSyntax>()
.FirstOrDefault();

VerifyDestructor(destructor);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private static bool IsPropertyCandidate(PropertyDeclarationSyntax propertySyntax
|| propertySymbol.OverriddenProperty == null
|| (propertySymbol.GetMethod != null && propertySymbol.OverriddenProperty.GetMethod == null)
|| (propertySymbol.SetMethod != null && propertySymbol.OverriddenProperty.SetMethod == null)
|| SymbolHelper.IsAnyAttributeInOverridingChain(propertySymbol))
|| propertySymbol.IsAnyAttributeInOverridingChain())
{
return false;
}
Expand Down Expand Up @@ -153,7 +153,7 @@ private static bool IsMethodCandidate(MethodDeclarationSyntax methodSyntax, Sema
|| IgnoredMethodNames.Contains(methodSymbol.Name)
|| methodSymbol.Parameters.Any(p => p.HasExplicitDefaultValue)
|| methodSymbol.OverriddenMethod.Parameters.Any(p => p.HasExplicitDefaultValue)
|| SymbolHelper.IsAnyAttributeInOverridingChain(methodSymbol)
|| methodSymbol.IsAnyAttributeInOverridingChain()
|| IsRecordCompilerGenerated(methodSymbol);

private static bool IsRecordCompilerGenerated(IMethodSymbol methodSymbol) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public sealed class PropertyNamesShouldNotMatchGetMethods : SonarDiagnosticAnaly
{
return;
}
var typeMembers = typeSymbol.GetMembers().Where(SymbolHelper.IsPubliclyAccessible);
var typeMembers = typeSymbol.GetMembers().Where(x => x.IsPubliclyAccessible());
var properties = typeMembers.OfType<IPropertySymbol>().Where(property => !property.IsOverride).ToArray();
var methods = typeMembers.OfType<IMethodSymbol>().ToArray();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2024 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.Extensions;

internal static class IMethodSymbolExtensions
{
public static bool IsExtensionOn(this IMethodSymbol methodSymbol, KnownType type)
{
if (methodSymbol is { IsExtensionMethod: true })
{
var receiverType = methodSymbol.MethodKind == MethodKind.Ordinary
? methodSymbol.Parameters.First().Type as INamedTypeSymbol
: methodSymbol.ReceiverType as INamedTypeSymbol;
return receiverType?.ConstructedFrom.Is(type) ?? false;
}
else
{
return false;
}
}

public static bool IsDestructor(this IMethodSymbol method) =>
method.MethodKind == MethodKind.Destructor;

public static bool IsAnyAttributeInOverridingChain(this IMethodSymbol method) =>
method.IsAnyAttributeInOverridingChain(x => x.OverriddenMethod);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,27 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.Extensions
namespace SonarAnalyzer.Extensions;

public static class INamedTypeSymbolExtensions
{
public static class INamedTypeSymbolExtensions
public static bool IsTopLevelProgram(this INamedTypeSymbol symbol) =>
TopLevelStatements.ProgramClassImplicitName.Contains(symbol.Name)
&& symbol.ContainingNamespace.IsGlobalNamespace
&& symbol.GetMembers(TopLevelStatements.MainMethodImplicitName).Any();

public static IEnumerable<INamedTypeSymbol> GetAllNamedTypes(this INamedTypeSymbol type)
{
public static bool IsTopLevelProgram(this INamedTypeSymbol symbol) =>
TopLevelStatements.ProgramClassImplicitName.Contains(symbol.Name)
&& symbol.ContainingNamespace.IsGlobalNamespace
&& symbol.GetMembers(TopLevelStatements.MainMethodImplicitName).Any();
if (type is null)
{
yield break;
}

yield return type;

foreach (var nestedType in type.GetTypeMembers().SelectMany(GetAllNamedTypes))
{
yield return nestedType;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ internal static class INamespaceSymbolExtensions
public static bool Is(this INamespaceSymbol symbol, string name)
{
_ = name ?? throw new ArgumentNullException(nameof(name));

var ns = name.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
var ns = name.Split(['.'], StringSplitOptions.RemoveEmptyEntries);
for (var i = ns.Length - 1; i >= 0; i--)
{
if (symbol is null || symbol.Name != ns[i])
Expand All @@ -46,4 +45,31 @@ public static bool Is(this INamespaceSymbol symbol, string name)
}
return symbol?.IsGlobalNamespace is true;
}

public static IEnumerable<INamedTypeSymbol> GetAllNamedTypes(this INamespaceSymbol @namespace)
{
if (@namespace is null)
{
yield break;
}
foreach (var typeMember in @namespace.GetTypeMembers().SelectMany(x => x.GetAllNamedTypes()))
{
yield return typeMember;
}
foreach (var typeMember in @namespace.GetNamespaceMembers().SelectMany(GetAllNamedTypes))
{
yield return typeMember;
}
}

public static bool IsSameNamespace(this INamespaceSymbol namespace1, INamespaceSymbol namespace2) =>
(namespace1.IsGlobalNamespace && namespace2.IsGlobalNamespace)
|| (namespace1.Name.Equals(namespace2.Name)
&& namespace1.ContainingNamespace is not null
&& namespace2.ContainingNamespace is not null
&& IsSameNamespace(namespace1.ContainingNamespace, namespace2.ContainingNamespace));

public static bool IsSameOrAncestorOf(this INamespaceSymbol thisNamespace, INamespaceSymbol namespaceToCheck) =>
IsSameNamespace(thisNamespace, namespaceToCheck)
|| (namespaceToCheck.ContainingNamespace is not null && IsSameOrAncestorOf(thisNamespace, namespaceToCheck.ContainingNamespace));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2024 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.Extensions;

internal static class IPropertySymbolExtensions
{
public static bool IsAnyAttributeInOverridingChain(this IPropertySymbol property) =>
property.IsAnyAttributeInOverridingChain(x => x.OverriddenProperty);
}

0 comments on commit ca0f118

Please sign in to comment.