Skip to content

Commit e7d7b4f

Browse files
perf: replace ManualSkipAny with Span extensions
1 parent 008a558 commit e7d7b4f

File tree

2 files changed

+58
-49
lines changed

2 files changed

+58
-49
lines changed

Src/CSharpier.Core/CSharp/SyntaxPrinter/SyntaxNodePrinters/InvocationExpression.cs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Diagnostics.CodeAnalysis;
22
using CSharpier.Core.DocTypes;
3+
using CSharpier.Core.Utilities;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CSharp;
56
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -65,9 +66,10 @@ public static Doc PrintMemberChain(ExpressionSyntax node, PrintingContext contex
6566
(
6667
groups.Length <= cutoff
6768
&& (
68-
groups.ManualSkipAny(
69-
shouldMergeFirstTwoGroups ? 1 : 0,
70-
o =>
69+
groups
70+
.AsSpan()
71+
.Skip(shouldMergeFirstTwoGroups ? 1 : 0)
72+
.Any(o =>
7173
o.Last().Node
7274
is not (
7375
InvocationExpressionSyntax
@@ -77,7 +79,7 @@ or PostfixUnaryExpressionSyntax
7779
Operand: InvocationExpressionSyntax
7880
}
7981
)
80-
)
82+
)
8183
// if the last group contains just a !, make sure it doesn't end up on a new line
8284
|| (
8385
groups[^1].Length == 1 && groups[^1][0].Node is PostfixUnaryExpressionSyntax
@@ -112,19 +114,10 @@ is LiteralExpressionSyntax
112114
return Doc.Group(oneLine);
113115
}
114116

115-
var expanded = Doc.Concat(
116-
Doc.Concat(groups[0].Select(o => o.Doc).ToArray()),
117-
shouldMergeFirstTwoGroups
118-
? Doc.IndentIf(
119-
groups.Length > 2 && groups[1].Last().Doc is not Group { Contents: IndentDoc },
120-
Doc.Concat(groups[1].Select(o => o.Doc).ToArray())
121-
)
122-
: Doc.Null,
123-
PrintIndentedGroup(groups.AsSpan()[(shouldMergeFirstTwoGroups ? 2 : 1)..])
124-
);
125-
117+
var expanded = IntoExpanded(groups, shouldMergeFirstTwoGroups);
118+
126119
return
127-
oneLine.ManualSkipAny(1, DocUtilities.ContainsBreak)
120+
oneLine.AsSpan().Skip(1).Any(DocUtilities.ContainsBreak)
128121
|| groups[0]
129122
.Any(o =>
130123
o.Node
@@ -140,11 +133,50 @@ is ParenthesizedExpressionSyntax
140133
parent is ExpressionStatementSyntax expressionStatementSyntax
141134
&& expressionStatementSyntax.SemicolonToken.LeadingTrivia.Any(o => o.IsComment())
142135
)
143-
|| groups.Count == 1
136+
|| groups.Length == 1
144137
? expanded
145138
: Doc.ConditionalGroup(Doc.Concat(oneLine), expanded);
146139
}
147140

141+
private static Doc IntoExpanded(
142+
ValueListBuilder<PrintedNode[]> groups,
143+
bool shouldMergeFirstTwoGroups
144+
)
145+
{
146+
var docs = new ValueListBuilder<Doc>([null, null, null, null, null, null, null, null]);
147+
148+
foreach (var item in groups[0])
149+
{
150+
docs.Append(item.Doc);
151+
}
152+
153+
if (shouldMergeFirstTwoGroups)
154+
{
155+
if (groups.Length > 2 && groups[1].Last().Doc is not Group { Contents: IndentDoc })
156+
{
157+
docs.Append(Doc.Indent(Doc.Concat(groups[1].Select(o => o.Doc).ToArray())));
158+
}
159+
else
160+
{
161+
foreach (var item in groups[1])
162+
{
163+
docs.Append(item.Doc);
164+
}
165+
}
166+
}
167+
168+
var indented = PrintIndentedGroup(groups.AsSpan()[(shouldMergeFirstTwoGroups ? 2 : 1)..]);
169+
170+
if (indented != Doc.Null)
171+
{
172+
docs.Append(indented);
173+
}
174+
175+
var returnDoc = Doc.Concat(ref docs);
176+
docs.Dispose();
177+
return returnDoc;
178+
}
179+
148180
private static void FlattenAndPrintNodes(
149181
ExpressionSyntax expression,
150182
ref ValueListBuilder<PrintedNode> printedNodes,
@@ -469,7 +501,7 @@ is SimpleLambdaExpressionSyntax
469501
or ArgumentSyntax
470502
or BinaryExpressionSyntax
471503
or ExpressionStatementSyntax
472-
|| groups[1].Skip(1).First().Node
504+
|| groups[1][1].Node
473505
is InvocationExpressionSyntax
474506
or ElementAccessExpressionSyntax
475507
or PostfixUnaryExpressionSyntax

Src/CSharpier.Core/Utilities/ListExtensions.cs

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,22 @@ public static void AddIfNotNull(this List<Doc> value, Doc doc)
3030
}
3131
}
3232

33-
public static bool ManualSkipAny<T>(
34-
ref this ValueListBuilder<T> collection,
35-
int count,
36-
Func<T, bool> predicate
37-
)
33+
public static bool Any<T>(this ReadOnlySpan<T> span, Func<T, bool> predicate)
3834
{
39-
if (predicate == null || count < 0)
40-
throw new ArgumentException("Invalid arguments");
41-
42-
int skipped = 0;
43-
foreach (var item in collection.AsSpan())
35+
foreach (var item in span)
4436
{
45-
if (skipped++ < count)
46-
continue; // Skip the first 'count' items
47-
4837
if (predicate(item))
49-
return true; // If any item satisfies the predicate, return true
38+
return true;
5039
}
5140

52-
return false; // No match found after skipping 'count' items
41+
return false;
5342
}
5443

55-
public static bool ManualSkipAny<T>(this T[] collection, int count, Func<T, bool> predicate)
56-
{
57-
if (collection == null || predicate == null || count < 0)
58-
throw new ArgumentException("Invalid arguments");
59-
60-
int skipped = 0;
61-
foreach (var item in collection)
62-
{
63-
if (skipped++ < count)
64-
continue; // Skip the first 'count' items
65-
66-
if (predicate(item))
67-
return true; // If any item satisfies the predicate, return true
68-
}
44+
public static ReadOnlySpan<T> Skip<T>(this ReadOnlySpan<T> span, int count) =>
45+
count > span.Length ? [] : span[count..];
6946

70-
return false; // No match found after skipping 'count' items
71-
}
47+
public static ReadOnlySpan<T> Skip<T>(this Span<T> span, int count) =>
48+
count > span.Length ? [] : span[count..];
7249

7350
// Overload for Any to prevent unnecessary allocations of EnumeratorImpl
7451
public static bool Any(this in SyntaxTriviaList triviaList, Func<SyntaxTrivia, bool> predicate)

0 commit comments

Comments
 (0)