Skip to content

Commit

Permalink
Merge pull request #1683 from sharwell/reduce-allocations
Browse files Browse the repository at this point in the history
Reduce allocations
  • Loading branch information
sharwell committed Oct 24, 2015
2 parents f1cfec3 + 598c3ea commit 49b706d
Show file tree
Hide file tree
Showing 59 changed files with 529 additions and 263 deletions.
41 changes: 40 additions & 1 deletion StyleCop.Analyzers/StyleCop.Analyzers/AnalyzerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace StyleCop.Analyzers
{
using System;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
Expand Down Expand Up @@ -86,6 +87,25 @@ public static ConcurrentDictionary<SyntaxTree, bool> GetOrCreateGeneratedDocumen
return headerCache.Item2;
}

/// <summary>
/// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an
/// appropriate kind. A syntax node action can report diagnostics about a <see cref="SyntaxNode"/>, and can also
/// collect state information to be used by other syntax node actions or code block end actions.
/// </summary>
/// <remarks>This method honors exclusions.</remarks>
/// <param name="context">Action will be executed only if the kind of a <see cref="SyntaxNode"/> matches
/// <paramref name="syntaxKind"/>.</param>
/// <param name="action">Action to be executed at completion of semantic analysis of a
/// <see cref="SyntaxNode"/>.</param>
/// <param name="syntaxKind">The kind of syntax that should be analyzed.</param>
/// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which
/// the action applies.</typeparam>
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, TLanguageKindEnum syntaxKind)
where TLanguageKindEnum : struct
{
context.RegisterSyntaxNodeActionHonorExclusions(action, LanguageKindArrays<TLanguageKindEnum>.GetOrCreateArray(syntaxKind));
}

/// <summary>
/// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an
/// appropriate kind. A syntax node action can report diagnostics about a <see cref="SyntaxNode"/>, and can also
Expand All @@ -99,7 +119,7 @@ public static ConcurrentDictionary<SyntaxTree, bool> GetOrCreateGeneratedDocumen
/// <param name="syntaxKinds">The kinds of syntax that should be analyzed.</param>
/// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which
/// the action applies.</typeparam>
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, params TLanguageKindEnum[] syntaxKinds)
public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(this CompilationStartAnalysisContext context, Action<SyntaxNodeAnalysisContext> action, ImmutableArray<TLanguageKindEnum> syntaxKinds)
where TLanguageKindEnum : struct
{
Compilation compilation = context.Compilation;
Expand All @@ -121,5 +141,24 @@ public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(th
},
syntaxKinds);
}

private static class LanguageKindArrays<TLanguageKindEnum>
where TLanguageKindEnum : struct
{
private static readonly ConcurrentDictionary<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>> Arrays =
new ConcurrentDictionary<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>>();

private static readonly Func<TLanguageKindEnum, ImmutableArray<TLanguageKindEnum>> CreateValueFactory = CreateValue;

public static ImmutableArray<TLanguageKindEnum> GetOrCreateArray(TLanguageKindEnum syntaxKind)
{
return Arrays.GetOrAdd(syntaxKind, CreateValueFactory);
}

private static ImmutableArray<TLanguageKindEnum> CreateValue(TLanguageKindEnum syntaxKind)
{
return ImmutableArray.Create(syntaxKind);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace StyleCop.Analyzers.DocumentationRules
{
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -16,11 +17,35 @@ namespace StyleCop.Analyzers.DocumentationRules
/// </summary>
internal abstract class ElementDocumentationSummaryBase : DiagnosticAnalyzer
{
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.EnumDeclaration);

private static readonly ImmutableArray<SyntaxKind> BaseFieldDeclarationKinds =
ImmutableArray.Create(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration);

private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
private readonly Action<SyntaxNodeAnalysisContext> typeDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> methodDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> constructorDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> destructorDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> propertyDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> indexerDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> fieldDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> delegateDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> eventDeclarationAction;

protected ElementDocumentationSummaryBase()
{
this.compilationStartAction = this.HandleCompilationStart;
this.typeDeclarationAction = this.HandleTypeDeclaration;
this.methodDeclarationAction = this.HandleMethodDeclaration;
this.constructorDeclarationAction = this.HandleConstructorDeclaration;
this.destructorDeclarationAction = this.HandleDestructorDeclaration;
this.propertyDeclarationAction = this.HandlePropertyDeclaration;
this.indexerDeclarationAction = this.HandleIndexerDeclaration;
this.fieldDeclarationAction = this.HandleFieldDeclaration;
this.delegateDeclarationAction = this.HandleDelegateDeclaration;
this.eventDeclarationAction = this.HandleEventDeclaration;
}

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

private void HandleCompilationStart(CompilationStartAnalysisContext context)
{
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.EnumDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleDestructorDeclaration, SyntaxKind.DestructorDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandlePropertyDeclaration, SyntaxKind.PropertyDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleIndexerDeclaration, SyntaxKind.IndexerDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleFieldDeclaration, SyntaxKind.FieldDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleDelegateDeclaration, SyntaxKind.DelegateDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleEventDeclaration, SyntaxKind.EventDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleFieldDeclaration, SyntaxKind.EventFieldDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.typeDeclarationAction, BaseTypeDeclarationKinds);
context.RegisterSyntaxNodeActionHonorExclusions(this.methodDeclarationAction, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.constructorDeclarationAction, SyntaxKind.ConstructorDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.destructorDeclarationAction, SyntaxKind.DestructorDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.propertyDeclarationAction, SyntaxKind.PropertyDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.indexerDeclarationAction, SyntaxKind.IndexerDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.fieldDeclarationAction, BaseFieldDeclarationKinds);
context.RegisterSyntaxNodeActionHonorExclusions(this.delegateDeclarationAction, SyntaxKind.DelegateDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.eventDeclarationAction, SyntaxKind.EventDeclaration);
}

private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace StyleCop.Analyzers.DocumentationRules
{
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -17,11 +18,18 @@ namespace StyleCop.Analyzers.DocumentationRules
/// </summary>
internal abstract class PartialElementDocumentationSummaryBase : DiagnosticAnalyzer
{
private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration);

private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
private readonly Action<SyntaxNodeAnalysisContext> baseTypeDeclarationAction;
private readonly Action<SyntaxNodeAnalysisContext> methodDeclarationAction;

protected PartialElementDocumentationSummaryBase()
{
this.compilationStartAction = this.HandleCompilationStart;
this.baseTypeDeclarationAction = this.HandleBaseTypeDeclaration;
this.methodDeclarationAction = this.HandleMethodDeclaration;
}

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

private void HandleCompilationStart(CompilationStartAnalysisContext context)
{
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.baseTypeDeclarationAction, BaseTypeDeclarationKinds);
context.RegisterSyntaxNodeActionHonorExclusions(this.methodDeclarationAction, SyntaxKind.MethodDeclaration);
}

private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
private void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
{
var node = (BaseTypeDeclarationSyntax)context.Node;
if (node.Identifier.IsMissing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ namespace StyleCop.Analyzers.DocumentationRules
internal abstract class PropertyDocumentationSummaryBase : DiagnosticAnalyzer
{
private readonly Action<CompilationStartAnalysisContext> compilationStartAction;
private readonly Action<SyntaxNodeAnalysisContext> propertyDeclarationAction;

protected PropertyDocumentationSummaryBase()
{
this.compilationStartAction = this.HandleCompilationStart;
this.propertyDeclarationAction = this.HandlePropertyDeclaration;
}

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

private void HandleCompilationStart(CompilationStartAnalysisContext context)
{
context.RegisterSyntaxNodeActionHonorExclusions(this.HandlePropertyDeclaration, SyntaxKind.PropertyDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(this.propertyDeclarationAction, SyntaxKind.PropertyDeclaration);
}

private void HandlePropertyDeclaration(SyntaxNodeAnalysisContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ internal class SA1600ElementsMustBeDocumented : DiagnosticAnalyzer
private static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);

private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.EnumDeclaration);

private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;

/// <inheritdoc/>
Expand All @@ -56,10 +59,7 @@ public override void Initialize(AnalysisContext context)
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
{
Analyzer analyzer = new Analyzer(context.Options);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.EnumDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleBaseTypeDeclaration, BaseTypeDeclarationKinds);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleDestructorDeclaration, SyntaxKind.DestructorDeclaration);
Expand All @@ -81,7 +81,7 @@ public Analyzer(AnalyzerOptions options)
this.documentationSettings = settings.DocumentationRules;
}

public void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
public void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
{
if (context.GetDocumentationMode() != DocumentationMode.Diagnose)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ internal class SA1601PartialElementsMustBeDocumented : DiagnosticAnalyzer
private static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);

private static readonly ImmutableArray<SyntaxKind> BaseTypeDeclarationKinds =
ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration);

private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;

/// <inheritdoc/>
Expand All @@ -97,9 +100,7 @@ public override void Initialize(AnalysisContext context)
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
{
Analyzer analyzer = new Analyzer(context.Options);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.ClassDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.InterfaceDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleTypeDeclaration, SyntaxKind.StructDeclaration);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleBaseTypeDeclaration, BaseTypeDeclarationKinds);
context.RegisterSyntaxNodeActionHonorExclusions(analyzer.HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
}

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

public void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
public void HandleBaseTypeDeclaration(SyntaxNodeAnalysisContext context)
{
if (context.GetDocumentationMode() != DocumentationMode.Diagnose)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ internal class SA1608ElementDocumentationMustNotHaveDefaultSummary : DiagnosticA
private static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);

private static readonly ImmutableArray<SyntaxKind> DocumentationCommentKinds =
ImmutableArray.Create(SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia);

private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
private static readonly Action<SyntaxNodeAnalysisContext> DocumentationAction = HandleDocumentation;

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

private static void HandleCompilationStart(CompilationStartAnalysisContext context)
{
context.RegisterSyntaxNodeActionHonorExclusions(HandleDocumentation, SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia);
context.RegisterSyntaxNodeActionHonorExclusions(DocumentationAction, DocumentationCommentKinds);
}

private static void HandleDocumentation(SyntaxNodeAnalysisContext context)
Expand Down
Loading

0 comments on commit 49b706d

Please sign in to comment.