Skip to content

Commit 693aec2

Browse files
committed
Simplify and optimize excluded span handling
1 parent a42e619 commit 693aec2

1 file changed

Lines changed: 32 additions & 105 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1027UseTabsCorrectly.cs

Lines changed: 32 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -60,124 +60,42 @@ private static void HandleCompilationStart(CompilationStartAnalysisContext conte
6060

6161
private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
6262
{
63-
SyntaxTree syntaxTree = context.Tree;
64-
SourceText sourceText = syntaxTree.GetText(context.CancellationToken);
65-
66-
ImmutableArray<TextSpan> convertToTabsSpans;
67-
ImmutableArray<TextSpan> convertToSpacesSpans;
68-
if (!LocateIncorrectTabUsage(sourceText, settings.Indentation, out convertToTabsSpans, out convertToSpacesSpans))
69-
{
70-
return;
71-
}
72-
73-
SyntaxNode root = syntaxTree.GetCompilationUnitRoot(context.CancellationToken);
63+
SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken);
7464
ImmutableArray<TextSpan> excludedSpans;
7565
if (!LocateExcludedSpans(root, out excludedSpans))
7666
{
7767
return;
7868
}
7969

80-
int toTabsIndex = 0;
81-
int toSpacesIndex = 0;
82-
83-
for (int excludedIndex = 0; excludedIndex < excludedSpans.Length; excludedIndex++)
84-
{
85-
TextSpan excluded = excludedSpans[excludedIndex];
86-
87-
while (toTabsIndex < convertToTabsSpans.Length)
88-
{
89-
TextSpan included = convertToTabsSpans[toTabsIndex];
90-
if (included.Start >= excluded.End)
91-
{
92-
// Doesn't overlap the current excluded span, but might overlap the next
93-
break;
94-
}
95-
96-
if (included.Start < excluded.Start)
97-
{
98-
int violationStart = included.Start;
99-
int violationEnd = Math.Min(included.End, excluded.Start);
100-
101-
context.ReportDiagnostic(
102-
Diagnostic.Create(
103-
Descriptor,
104-
Location.Create(syntaxTree, TextSpan.FromBounds(violationStart, violationEnd)),
105-
ConvertToTabsProperties));
106-
}
107-
108-
if (included.End > excluded.End)
109-
{
110-
// It overlapped the current excluded span, and might also overlap the next
111-
break;
112-
}
113-
114-
toTabsIndex++;
115-
}
116-
117-
while (toSpacesIndex < convertToSpacesSpans.Length)
118-
{
119-
TextSpan included = convertToSpacesSpans[toSpacesIndex];
120-
if (included.Start >= excluded.End)
121-
{
122-
// Doesn't overlap the current excluded span, but might overlap the next
123-
break;
124-
}
125-
126-
if (included.Start < excluded.Start)
127-
{
128-
int violationStart = included.Start;
129-
int violationEnd = Math.Min(included.End, excluded.Start);
130-
131-
context.ReportDiagnostic(
132-
Diagnostic.Create(
133-
Descriptor,
134-
Location.Create(syntaxTree, TextSpan.FromBounds(violationStart, violationEnd)),
135-
ConvertToSpacesProperties));
136-
}
137-
138-
if (included.End > excluded.End)
139-
{
140-
// It overlapped the current excluded span, and might also overlap the next
141-
break;
142-
}
143-
144-
toSpacesIndex++;
145-
}
146-
}
147-
148-
for (; toTabsIndex < convertToTabsSpans.Length; toTabsIndex++)
149-
{
150-
context.ReportDiagnostic(
151-
Diagnostic.Create(
152-
Descriptor,
153-
Location.Create(syntaxTree, convertToTabsSpans[toTabsIndex]),
154-
ConvertToTabsProperties));
155-
}
156-
157-
for (; toSpacesIndex < convertToSpacesSpans.Length; toSpacesIndex++)
158-
{
159-
context.ReportDiagnostic(
160-
Diagnostic.Create(
161-
Descriptor,
162-
Location.Create(syntaxTree, convertToSpacesSpans[toSpacesIndex]),
163-
ConvertToSpacesProperties));
164-
}
70+
ReportIncorrectTabUsage(context, settings.Indentation, excludedSpans);
16571
}
16672

167-
private static bool LocateIncorrectTabUsage(SourceText sourceText, IndentationSettings indentationSettings, out ImmutableArray<TextSpan> convertToTabsSpans, out ImmutableArray<TextSpan> convertToSpacesSpans)
73+
private static void ReportIncorrectTabUsage(SyntaxTreeAnalysisContext context, IndentationSettings indentationSettings, ImmutableArray<TextSpan> excludedSpans)
16874
{
169-
ImmutableArray<TextSpan>.Builder toTabsBuilder = ImmutableArray.CreateBuilder<TextSpan>();
170-
ImmutableArray<TextSpan>.Builder toSpacesBuilder = ImmutableArray.CreateBuilder<TextSpan>();
75+
SyntaxTree syntaxTree = context.Tree;
76+
SourceText sourceText = syntaxTree.GetText(context.CancellationToken);
17177

17278
string completeText = sourceText.ToString();
17379
int length = completeText.Length;
17480

17581
bool useTabs = indentationSettings.UseTabs;
17682
int tabSize = indentationSettings.TabSize;
17783

84+
int excludedSpanIndex = 0;
85+
var lastExcludedSpan = new TextSpan(completeText.Length, 0);
86+
TextSpan nextExcludedSpan = !excludedSpans.IsEmpty ? excludedSpans[0] : lastExcludedSpan;
87+
17888
int lastLineStart = 0;
17989
for (int startIndex = 0; startIndex < length; startIndex++)
18090
{
91+
if (startIndex == nextExcludedSpan.Start)
92+
{
93+
startIndex = nextExcludedSpan.End - 1;
94+
excludedSpanIndex++;
95+
nextExcludedSpan = excludedSpanIndex < excludedSpans.Length ? excludedSpans[excludedSpanIndex] : lastExcludedSpan;
96+
continue;
97+
}
98+
18199
int tabCount = 0;
182100
bool containsSpaces = false;
183101
bool tabAfterSpace = false;
@@ -205,6 +123,11 @@ private static bool LocateIncorrectTabUsage(SourceText sourceText, IndentationSe
205123
int endIndex;
206124
for (endIndex = startIndex + 1; endIndex < length; endIndex++)
207125
{
126+
if (endIndex == nextExcludedSpan.Start)
127+
{
128+
break;
129+
}
130+
208131
if (completeText[endIndex] == ' ')
209132
{
210133
containsSpaces = true;
@@ -227,24 +150,28 @@ private static bool LocateIncorrectTabUsage(SourceText sourceText, IndentationSe
227150
int spaceCount = (endIndex - startIndex) - tabCount;
228151
if (tabAfterSpace || spaceCount >= tabSize)
229152
{
230-
toTabsBuilder.Add(TextSpan.FromBounds(startIndex, endIndex));
153+
context.ReportDiagnostic(
154+
Diagnostic.Create(
155+
Descriptor,
156+
Location.Create(syntaxTree, TextSpan.FromBounds(startIndex, endIndex)),
157+
ConvertToTabsProperties));
231158
}
232159
}
233160
else
234161
{
235162
if (tabCount > 0)
236163
{
237-
toSpacesBuilder.Add(TextSpan.FromBounds(startIndex, endIndex));
164+
context.ReportDiagnostic(
165+
Diagnostic.Create(
166+
Descriptor,
167+
Location.Create(syntaxTree, TextSpan.FromBounds(startIndex, endIndex)),
168+
ConvertToSpacesProperties));
238169
}
239170
}
240171

241172
// Make sure to not analyze overlapping spans
242173
startIndex = endIndex - 1;
243174
}
244-
245-
convertToTabsSpans = toTabsBuilder.ToImmutable();
246-
convertToSpacesSpans = toSpacesBuilder.ToImmutable();
247-
return true;
248175
}
249176

250177
private static bool LocateExcludedSpans(SyntaxNode root, out ImmutableArray<TextSpan> excludedSpans)

0 commit comments

Comments
 (0)