Skip to content

Commit 49b706d

Browse files
committed
Merge pull request #1683 from sharwell/reduce-allocations
Reduce allocations
2 parents f1cfec3 + 598c3ea commit 49b706d

59 files changed

Lines changed: 529 additions & 263 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

StyleCop.Analyzers/StyleCop.Analyzers/AnalyzerExtensions.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace StyleCop.Analyzers
55
{
66
using System;
77
using System.Collections.Concurrent;
8+
using System.Collections.Immutable;
89
using System.Threading;
910
using Microsoft.CodeAnalysis;
1011
using Microsoft.CodeAnalysis.Diagnostics;
@@ -86,6 +87,25 @@ public static ConcurrentDictionary<SyntaxTree, bool> GetOrCreateGeneratedDocumen
8687
return headerCache.Item2;
8788
}
8889

90+
/// <summary>
91+
/// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an
92+
/// appropriate kind. A syntax node action can report diagnostics about a <see cref="SyntaxNode"/>, and can also
93+
/// collect state information to be used by other syntax node actions or code block end actions.
94+
/// </summary>
95+
/// <remarks>This method honors exclusions.</remarks>
96+
/// <param name="context">Action will be executed only if the kind of a <see cref="SyntaxNode"/> matches
97+
/// <paramref name="syntaxKind"/>.</param>
98+
/// <param name="action">Action to be executed at completion of semantic analysis of a
99+
/// <see cref="SyntaxNode"/>.</param>
100+
/// <param name="syntaxKind">The kind of syntax that should be analyzed.</param>
101+
/// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which
102+
/// the action applies.</typeparam>
103+
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, TLanguageKindEnum syntaxKind)
104+
where TLanguageKindEnum : struct
105+
{
106+
context.RegisterSyntaxNodeActionHonorExclusions(action, LanguageKindArrays<TLanguageKindEnum>.GetOrCreateArray(syntaxKind));
107+
}
108+
89109
/// <summary>
90110
/// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an
91111
/// appropriate kind. A syntax node action can report diagnostics about a <see cref="SyntaxNode"/>, and can also
@@ -99,7 +119,7 @@ public static ConcurrentDictionary<SyntaxTree, bool> GetOrCreateGeneratedDocumen
99119
/// <param name="syntaxKinds">The kinds of syntax that should be analyzed.</param>
100120
/// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which
101121
/// the action applies.</typeparam>
102-
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, params TLanguageKindEnum[] syntaxKinds)
122+
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds)
103123
where TLanguageKindEnum : struct
104124
{
105125
Compilation compilation = context.Compilation;
@@ -121,5 +141,24 @@ public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(th
121141
},
122142
syntaxKinds);
123143
}
144+
145+
private static class LanguageKindArrays<TLanguageKindEnum>
146+
where TLanguageKindEnum : struct
147+
{
148+
private static readonly ConcurrentDictionary<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>> Arrays =
149+
new ConcurrentDictionary<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>>();
150+
151+
private static readonly Func<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>> CreateValueFactory = CreateValue;
152+
153+
public static ImmutableArray<TLanguageKindEnum> GetOrCreateArray(TLanguageKindEnum syntaxKind)
154+
{
155+
return Arrays.GetOrAdd(syntaxKind, CreateValueFactory);
156+
}
157+
158+
private static ImmutableArray<TLanguageKindEnum> CreateValue(TLanguageKindEnum syntaxKind)
159+
{
160+
return ImmutableArray.Create(syntaxKind);
161+
}
162+
}
124163
}
125164
}

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/ElementDocumentationSummaryBase.cs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace StyleCop.Analyzers.DocumentationRules
55
{
66
using System;
7+
using System.Collections.Immutable;
78
using System.Linq;
89
using Microsoft.CodeAnalysis;
910
using Microsoft.CodeAnalysis.CSharp;
@@ -16,11 +17,35 @@ namespace StyleCop.Analyzers.DocumentationRules
1617
/// </summary>
1718
internal abstract class ElementDocumentationSummaryBase : DiagnosticAnalyzer
1819
{
20+
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
21+
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.EnumDeclaration);
22+
23+
private static readonly ImmutableArray<SyntaxKind> BaseFieldDeclarationKinds =
24+
ImmutableArray.Create(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration);
25+
1926
private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
27+
private readonly Action<SyntaxNodeAnalysisContext> typeDeclarationAction;
28+
private readonly Action<SyntaxNodeAnalysisContext> methodDeclarationAction;
29+
private readonly Action<SyntaxNodeAnalysisContext> constructorDeclarationAction;
30+
private readonly Action<SyntaxNodeAnalysisContext> destructorDeclarationAction;
31+
private readonly Action<SyntaxNodeAnalysisContext> propertyDeclarationAction;
32+
private readonly Action<SyntaxNodeAnalysisContext> indexerDeclarationAction;
33+
private readonly Action<SyntaxNodeAnalysisContext> fieldDeclarationAction;
34+
private readonly Action<SyntaxNodeAnalysisContext> delegateDeclarationAction;
35+
private readonly Action<SyntaxNodeAnalysisContext> eventDeclarationAction;
2036

2137
protected ElementDocumentationSummaryBase()
2238
{
2339
this.compilationStartAction = this.HandleCompilationStart;
40+
this.typeDeclarationAction = this.HandleTypeDeclaration;
41+
this.methodDeclarationAction = this.HandleMethodDeclaration;
42+
this.constructorDeclarationAction = this.HandleConstructorDeclaration;
43+
this.destructorDeclarationAction = this.HandleDestructorDeclaration;
44+
this.propertyDeclarationAction = this.HandlePropertyDeclaration;
45+
this.indexerDeclarationAction = this.HandleIndexerDeclaration;
46+
this.fieldDeclarationAction = this.HandleFieldDeclaration;
47+
this.delegateDeclarationAction = this.HandleDelegateDeclaration;
48+
this.eventDeclarationAction = this.HandleEventDeclaration;
2449
}
2550

2651
/// <inheritdoc/>
@@ -40,19 +65,15 @@ public override void Initialize(AnalysisContext context)
4065

4166
private void HandleCompilationStart(CompilationStartAnalysisContext context)
4267
{
43-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
44-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
45-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
46-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.EnumDeclaration);
47-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
48-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
49-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleDestructorDeclaration, SyntaxKind.DestructorDeclaration);
50-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandlePropertyDeclaration, SyntaxKind.PropertyDeclaration);
51-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleIndexerDeclaration, SyntaxKind.IndexerDeclaration);
52-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleFieldDeclaration, SyntaxKind.FieldDeclaration);
53-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleDelegateDeclaration, SyntaxKind.DelegateDeclaration);
54-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleEventDeclaration, SyntaxKind.EventDeclaration);
55-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleFieldDeclaration, SyntaxKind.EventFieldDeclaration);
68+
context.RegisterSyntaxNodeActionHonorExclusions(this.typeDeclarationAction, BaseTypeDeclarationKinds);
69+
context.RegisterSyntaxNodeActionHonorExclusions(this.methodDeclarationAction, SyntaxKind.MethodDeclaration);
70+
context.RegisterSyntaxNodeActionHonorExclusions(this.constructorDeclarationAction, SyntaxKind.ConstructorDeclaration);
71+
context.RegisterSyntaxNodeActionHonorExclusions(this.destructorDeclarationAction, SyntaxKind.DestructorDeclaration);
72+
context.RegisterSyntaxNodeActionHonorExclusions(this.propertyDeclarationAction, SyntaxKind.PropertyDeclaration);
73+
context.RegisterSyntaxNodeActionHonorExclusions(this.indexerDeclarationAction, SyntaxKind.IndexerDeclaration);
74+
context.RegisterSyntaxNodeActionHonorExclusions(this.fieldDeclarationAction, BaseFieldDeclarationKinds);
75+
context.RegisterSyntaxNodeActionHonorExclusions(this.delegateDeclarationAction, SyntaxKind.DelegateDeclaration);
76+
context.RegisterSyntaxNodeActionHonorExclusions(this.eventDeclarationAction, SyntaxKind.EventDeclaration);
5677
}
5778

5879
private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/PartialElementDocumentationSummaryBase.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace StyleCop.Analyzers.DocumentationRules
55
{
66
using System;
7+
using System.Collections.Immutable;
78
using System.Linq;
89
using Microsoft.CodeAnalysis;
910
using Microsoft.CodeAnalysis.CSharp;
@@ -17,11 +18,18 @@ namespace StyleCop.Analyzers.DocumentationRules
1718
/// </summary>
1819
internal abstract class PartialElementDocumentationSummaryBase : DiagnosticAnalyzer
1920
{
21+
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
22+
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration);
23+
2024
private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
25+
private readonly Action<SyntaxNodeAnalysisContext> baseTypeDeclarationAction;
26+
private readonly Action<SyntaxNodeAnalysisContext> methodDeclarationAction;
2127

2228
protected PartialElementDocumentationSummaryBase()
2329
{
2430
this.compilationStartAction = this.HandleCompilationStart;
31+
this.baseTypeDeclarationAction = this.HandleBaseTypeDeclaration;
32+
this.methodDeclarationAction = this.HandleMethodDeclaration;
2533
}
2634

2735
/// <inheritdoc/>
@@ -41,13 +49,11 @@ public override void Initialize(AnalysisContext context)
4149

4250
private void HandleCompilationStart(CompilationStartAnalysisContext context)
4351
{
44-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
45-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
46-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
47-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
52+
context.RegisterSyntaxNodeActionHonorExclusions(this.baseTypeDeclarationAction, BaseTypeDeclarationKinds);
53+
context.RegisterSyntaxNodeActionHonorExclusions(this.methodDeclarationAction, SyntaxKind.MethodDeclaration);
4854
}
4955

50-
private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
56+
private void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
5157
{
5258
var node = (BaseTypeDeclarationSyntax)context.Node;
5359
if (node.Identifier.IsMissing)

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/PropertyDocumentationSummaryBase.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ namespace StyleCop.Analyzers.DocumentationRules
1616
internal abstract class PropertyDocumentationSummaryBase : DiagnosticAnalyzer
1717
{
1818
private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
19+
private readonly Action<SyntaxNodeAnalysisContext> propertyDeclarationAction;
1920

2021
protected PropertyDocumentationSummaryBase()
2122
{
2223
this.compilationStartAction = this.HandleCompilationStart;
24+
this.propertyDeclarationAction = this.HandlePropertyDeclaration;
2325
}
2426

2527
/// <inheritdoc/>
@@ -39,7 +41,7 @@ public override void Initialize(AnalysisContext context)
3941

4042
private void HandleCompilationStart(CompilationStartAnalysisContext context)
4143
{
42-
context.RegisterSyntaxNodeActionHonorExclusions(this.HandlePropertyDeclaration, SyntaxKind.PropertyDeclaration);
44+
context.RegisterSyntaxNodeActionHonorExclusions(this.propertyDeclarationAction, SyntaxKind.PropertyDeclaration);
4345
}
4446

4547
private void HandlePropertyDeclaration(SyntaxNodeAnalysisContext context)

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1600ElementsMustBeDocumented.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ internal class SA1600ElementsMustBeDocumented : DiagnosticAnalyzer
4141
private static readonly DiagnosticDescriptor Descriptor =
4242
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
4343

44+
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
45+
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.EnumDeclaration);
46+
4447
private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
4548

4649
/// <inheritdoc/>
@@ -56,10 +59,7 @@ public override void Initialize(AnalysisContext context)
5659
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
5760
{
5861
Analyzer analyzer = new Analyzer(context.Options);
59-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
60-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
61-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
62-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.EnumDeclaration);
62+
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleBaseTypeDeclaration, BaseTypeDeclarationKinds);
6363
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
6464
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
6565
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleDestructorDeclaration, SyntaxKind.DestructorDeclaration);
@@ -81,7 +81,7 @@ public Analyzer(AnalyzerOptions options)
8181
this.documentationSettings = settings.DocumentationRules;
8282
}
8383

84-
public void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
84+
public void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
8585
{
8686
if (context.GetDocumentationMode() != DocumentationMode.Diagnose)
8787
{

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1601PartialElementsMustBeDocumented.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ internal class SA1601PartialElementsMustBeDocumented : DiagnosticAnalyzer
8282
private static readonly DiagnosticDescriptor Descriptor =
8383
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
8484

85+
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
86+
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration);
87+
8588
private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
8689

8790
/// <inheritdoc/>
@@ -97,9 +100,7 @@ public override void Initialize(AnalysisContext context)
97100
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
98101
{
99102
Analyzer analyzer = new Analyzer(context.Options);
100-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
101-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
102-
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
103+
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleBaseTypeDeclaration, BaseTypeDeclarationKinds);
103104
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
104105
}
105106

@@ -113,7 +114,7 @@ public Analyzer(AnalyzerOptions options)
113114
this.documentationSettings = settings.DocumentationRules;
114115
}
115116

116-
public void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
117+
public void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
117118
{
118119
if (context.GetDocumentationMode() != DocumentationMode.Diagnose)
119120
{

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1608ElementDocumentationMustNotHaveDefaultSummary.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ internal class SA1608ElementDocumentationMustNotHaveDefaultSummary : DiagnosticA
4747
private static readonly DiagnosticDescriptor Descriptor =
4848
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
4949

50+
private static readonly ImmutableArray<SyntaxKind> DocumentationCommentKinds =
51+
ImmutableArray.Create(SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia);
52+
5053
private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
54+
private static readonly Action<SyntaxNodeAnalysisContext> DocumentationAction = HandleDocumentation;
5155

5256
/// <inheritdoc/>
5357
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } =
@@ -61,7 +65,7 @@ public override void Initialize(AnalysisContext context)
6165

6266
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
6367
{
64-
context.RegisterSyntaxNodeActionHonorExclusions(HandleDocumentation, SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia);
68+
context.RegisterSyntaxNodeActionHonorExclusions(DocumentationAction, DocumentationCommentKinds);
6569
}
6670

6771
private static void HandleDocumentation(SyntaxNodeAnalysisContext context)

0 commit comments

Comments
 (0)