Skip to content

Commit

Permalink
performance optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfKoban committed Jan 28, 2025
1 parent 27ce128 commit 0433e95
Show file tree
Hide file tree
Showing 29 changed files with 298 additions and 111 deletions.
58 changes: 42 additions & 16 deletions MiKo.Analyzer.Shared/Extensions/SyntaxNodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,10 +1252,7 @@ internal static string GetTextWithoutTrivia(this XmlTextSyntax value)

var builder = StringBuilderCache.Acquire();

foreach (var valueText in value.GetTextWithoutTriviaLazy())
{
builder.Append(valueText);
}
GetTextWithoutTrivia(value, builder);

var trimmed = builder.Trim();

Expand All @@ -1264,6 +1261,36 @@ internal static string GetTextWithoutTrivia(this XmlTextSyntax value)
return trimmed;
}

internal static StringBuilder GetTextWithoutTrivia(this XmlTextSyntax value, StringBuilder builder)
{
if (value is null)
{
return builder;
}

var textTokens = value.TextTokens;

// keep in local variable to avoid multiple requests (see Roslyn implementation)
var textTokensCount = textTokens.Count;

if (textTokensCount > 0)
{
for (var index = 0; index < textTokensCount; index++)
{
var token = textTokens[index];

if (token.IsKind(SyntaxKind.XmlTextLiteralNewLineToken))
{
continue;
}

builder.Append(token.WithoutTrivia().ValueText);
}
}

return builder;
}

internal static StringBuilder GetTextWithoutTrivia(this XmlElementSyntax value, StringBuilder builder)
{
if (value is null)
Expand All @@ -1276,21 +1303,28 @@ internal static StringBuilder GetTextWithoutTrivia(this XmlElementSyntax value,
// keep in local variable to avoid multiple requests (see Roslyn implementation)
var contentCount = content.Count;

if (content.Count > 0)
if (contentCount > 0)
{
for (var index = 0; index < contentCount; index++)
{
var node = content[index];
var tagName = node.GetXmlTagName();

if (tagName == Constants.XmlTag.C)
switch (tagName)
{
// ignore code
continue;
case "i":
case "b":
case Constants.XmlTag.C:
continue; // ignore code
}

switch (node)
{
case XmlTextSyntax text:
GetTextWithoutTrivia(text, builder);

break;

case XmlEmptyElementSyntax empty:
builder.Append(empty.WithoutTrivia());

Expand All @@ -1299,14 +1333,6 @@ internal static StringBuilder GetTextWithoutTrivia(this XmlElementSyntax value,
case XmlElementSyntax e:
GetTextWithoutTrivia(e, builder);

break;

case XmlTextSyntax text:
foreach (var valueText in text.GetTextWithoutTriviaLazy())
{
builder.Append(valueText);
}

break;
}
}
Expand Down
8 changes: 4 additions & 4 deletions MiKo.Analyzer.Shared/Linguistics/Pluralizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public static bool IsPlural(ReadOnlySpan<char> value)
/// The name to create a plural for.
/// </param>
/// <returns>
/// The plural for the given <paramref name="name"/>.
/// A <see cref="string"/> that contains the plural for the given <paramref name="name"/>.
/// </returns>
public static string MakePluralName(string name) => GetPluralName(name, StringComparison.Ordinal) ?? name;

Expand All @@ -97,7 +97,7 @@ public static bool IsPlural(ReadOnlySpan<char> value)
/// One of the <see cref="StringComparison"/> values that specifies the rules for comparison.
/// </param>
/// <returns>
/// The plural for the given <paramref name="name"/>.
/// A <see cref="string"/> that contains the plural for the given <paramref name="name"/>.
/// </returns>
public static string GetPluralName(string name, StringComparison comparison = StringComparison.OrdinalIgnoreCase) => GetPluralName(name, name, comparison);

Expand All @@ -114,7 +114,7 @@ public static bool IsPlural(ReadOnlySpan<char> value)
/// One of the <see cref="StringComparison"/> values that specifies the rules for comparison.
/// </param>
/// <returns>
/// The plural for the given <paramref name="name"/>.
/// A <see cref="string"/> that contains the plural for the given <paramref name="name"/>.
/// </returns>
public static string GetPluralName(string name, string proposedName, StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
Expand All @@ -139,7 +139,7 @@ public static string GetPluralName(string name, string proposedName, StringCompa
/// The suffixes to remove from the plural name.
/// </param>
/// <returns>
/// The plural for the given <paramref name="name"/>.
/// A <see cref="string"/> that contains the plural for the given <paramref name="name"/>.
/// </returns>
public static string GetPluralName(string name, StringComparison comparison = StringComparison.OrdinalIgnoreCase, params string[] suffixes)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ private static IReadOnlyList<Location> GetAllLocations(string text, SyntaxTree s

var allIndices = text.AllIndicesOf(value, comparison);

if (allIndices.IsEmptyArray())
if (allIndices is int[] array && array.Length == 0)
{
// nothing to inspect
return Array.Empty<Location>();
Expand Down Expand Up @@ -464,7 +464,7 @@ private static IReadOnlyList<Location> GetAllLocations(string text, SyntaxTree s

var allIndices = text.AllIndicesOf(value, comparison);

if (allIndices.IsEmptyArray())
if (allIndices is int[] array && array.Length == 0)
{
// nothing to inspect
return Array.Empty<Location>();
Expand Down Expand Up @@ -536,7 +536,7 @@ private static IReadOnlyList<Location> GetAllLocationsWithLoop(string text, Synt

var allIndices = text.AllIndicesOf(value, comparison);

if (allIndices.IsEmptyArray())
if (allIndices is int[] array && array.Length == 0)
{
// nothing to inspect
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, Constants.Comments.EventArgsTermsWithDelimiters, StringComparison.OrdinalIgnoreCase, Offset, Offset))
var locations = GetAllLocations(token, Constants.Comments.EventArgsTermsWithDelimiters, StringComparison.OrdinalIgnoreCase, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
foreach (var token in comment.GetXmlTextTokens())
{
foreach (var location in GetAllLocations(token, ForbiddenPhrases, StringComparison.OrdinalIgnoreCase))
var locations = GetAllLocations(token, ForbiddenPhrases, StringComparison.OrdinalIgnoreCase);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location, AllowedWordsForRule, ForbiddenWordsForRule);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index], AllowedWordsForRule, ForbiddenWordsForRule);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ public sealed class MiKo_2022_OutParamDefaultPhraseAnalyzer : ParamDocumentation
{
public const string Id = "MiKo_2022";

public MiKo_2022_OutParamDefaultPhraseAnalyzer() : base(Id)
{
}
public MiKo_2022_OutParamDefaultPhraseAnalyzer() : base(Id) => IgnoreEmptyParameters = false;

protected override bool ShallAnalyzeParameter(IParameterSymbol parameter) => parameter.RefKind == RefKind.Out;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ public sealed class MiKo_2023_BooleanParamDefaultPhraseAnalyzer : ParamDocumenta
private static readonly string[] EndingPhrases = Constants.Comments.BooleanParameterEndingPhrase;
private static readonly string EndingPhrase = EndingPhrases[0];

public MiKo_2023_BooleanParamDefaultPhraseAnalyzer() : base(Id)
{
}
public MiKo_2023_BooleanParamDefaultPhraseAnalyzer() : base(Id) => IgnoreEmptyParameters = false;

protected override bool ShallAnalyzeParameter(IParameterSymbol parameter) => parameter.Type.IsBoolean()
&& parameter.RefKind != RefKind.Out
&& parameter.GetEnclosingMethod().Name != nameof(IDisposable.Dispose);
&& parameter.RefKind != RefKind.Out
&& parameter.GetEnclosingMethod().Name != nameof(IDisposable.Dispose);

protected override IEnumerable<Diagnostic> AnalyzeParameter(IParameterSymbol parameter, XmlElementSyntax parameterComment, string comment)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, BooleanPhrases, StringComparison.Ordinal, Offset, Offset))
var locations = GetAllLocations(token, BooleanPhrases, StringComparison.Ordinal, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ public sealed class MiKo_2074_ContainsParameterDefaultPhraseAnalyzer : ParamDocu

private static readonly string[] Phrases = { " to seek.", " to locate." };

public MiKo_2074_ContainsParameterDefaultPhraseAnalyzer() : base(Id)
{
}
public MiKo_2074_ContainsParameterDefaultPhraseAnalyzer() : base(Id) => IgnoreEmptyParameters = false;

protected override bool ShallAnalyze(IMethodSymbol symbol) => symbol.Name.StartsWith("Contains", StringComparison.OrdinalIgnoreCase) && symbol.Parameters.Any() && base.ShallAnalyze(symbol);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, ActionTermsWithDelimiters, StringComparison.Ordinal, Offset, Offset))
var locations = GetAllLocations(token, ActionTermsWithDelimiters, StringComparison.Ordinal, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(location, Constants.Comments.CallbackTerm);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(locations[index], Constants.Comments.CallbackTerm);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ public sealed class MiKo_2076_OptionalParameterDefaultPhraseAnalyzer : ParamDocu
"Defaults to",
};

public MiKo_2076_OptionalParameterDefaultPhraseAnalyzer() : base(Id)
{
}
public MiKo_2076_OptionalParameterDefaultPhraseAnalyzer() : base(Id) => IgnoreEmptyParameters = false;

protected override bool ShallAnalyze(IMethodSymbol symbol) => symbol.Parameters.Any(_ => _.HasExplicitDefaultValue) && base.ShallAnalyze(symbol);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ private IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, DocumentationComm
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, Constants.Comments.IdTerms, StringComparison.OrdinalIgnoreCase, Offset, Offset))
var locations = GetAllLocations(token, Constants.Comments.IdTerms, StringComparison.OrdinalIgnoreCase, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ private IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, DocumentationComm
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, Constants.Comments.GuidTermsWithDelimiters, StringComparison.Ordinal, Offset, Offset))
var locations = GetAllLocations(token, Constants.Comments.GuidTermsWithDelimiters, StringComparison.Ordinal, Offset, Offset);

var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ private IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, DocumentationComm
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, Triggers, StringComparison.OrdinalIgnoreCase, Offset, Offset))
var locations = GetAllLocations(token, Triggers, StringComparison.OrdinalIgnoreCase, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
foreach (var token in comment.GetXmlTextTokens())
{
foreach (var location in GetAllLocations(token, Triggers, StringComparison.OrdinalIgnoreCase))
var locations = GetAllLocations(token, Triggers, StringComparison.OrdinalIgnoreCase);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(symbol.Name, location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(symbol.Name, locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
const int Offset = 1; // we do not want to underline the first and last char

foreach (var location in GetAllLocations(token, Constants.Comments.FlagTermsWithDelimiters, StringComparison.OrdinalIgnoreCase, Offset, Offset))
var locations = GetAllLocations(token, Constants.Comments.FlagTermsWithDelimiters, StringComparison.OrdinalIgnoreCase, Offset, Offset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(locations[index]);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ protected override IEnumerable<Diagnostic> AnalyzeComment(ISymbol symbol, Compil
{
const int EndOffset = 1; // we do not want to underline the last char

foreach (var location in GetAllLocations(token, Constants.Comments.InstanceOfPhrases, StringComparison.Ordinal, 0, EndOffset))
var locations = GetAllLocations(token, Constants.Comments.InstanceOfPhrases, StringComparison.Ordinal, 0, EndOffset);
var locationsCount = locations.Count;

if (locationsCount > 0)
{
yield return Issue(location);
for (var index = 0; index < locationsCount; index++)
{
yield return Issue(locations[index]);
}
}
}
}
Expand Down
Loading

0 comments on commit 0433e95

Please sign in to comment.