@@ -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
@@ -101,6 +121,32 @@ public static ConcurrentDictionary<SyntaxTree, bool> GetOrCreateGeneratedDocumen
101121 /// the action applies.</typeparam>
102122 public static void RegisterSyntaxNodeActionHonorExclusions < TLanguageKindEnum > ( this CompilationStartAnalysisContext context , Action < SyntaxNodeAnalysisContext > action , params TLanguageKindEnum [ ] syntaxKinds )
103123 where TLanguageKindEnum : struct
124+ {
125+ if ( syntaxKinds == null )
126+ {
127+ RegisterSyntaxNodeActionHonorExclusions ( context , action , default ( ImmutableArray < TLanguageKindEnum > ) ) ;
128+ }
129+ else
130+ {
131+ RegisterSyntaxNodeActionHonorExclusions ( context , action , syntaxKinds . ToImmutableArray ( ) ) ;
132+ }
133+ }
134+
135+ /// <summary>
136+ /// Register an action to be executed at completion of semantic analysis of a <see cref="SyntaxNode"/> with an
137+ /// appropriate kind. A syntax node action can report diagnostics about a <see cref="SyntaxNode"/>, and can also
138+ /// collect state information to be used by other syntax node actions or code block end actions.
139+ /// </summary>
140+ /// <remarks>This method honors exclusions.</remarks>
141+ /// <param name="context">Action will be executed only if the kind of a <see cref="SyntaxNode"/> matches one of
142+ /// the <paramref name="syntaxKinds"/> values.</param>
143+ /// <param name="action">Action to be executed at completion of semantic analysis of a
144+ /// <see cref="SyntaxNode"/>.</param>
145+ /// <param name="syntaxKinds">The kinds of syntax that should be analyzed.</param>
146+ /// <typeparam name="TLanguageKindEnum">Enum type giving the syntax node kinds of the source language for which
147+ /// the action applies.</typeparam>
148+ public static void RegisterSyntaxNodeActionHonorExclusions < TLanguageKindEnum > ( this CompilationStartAnalysisContext context , Action < SyntaxNodeAnalysisContext > action , ImmutableArray < TLanguageKindEnum > syntaxKinds )
149+ where TLanguageKindEnum : struct
104150 {
105151 Compilation compilation = context . Compilation ;
106152 ConcurrentDictionary < SyntaxTree , bool > cache = GetOrCreateGeneratedDocumentCache ( compilation ) ;
@@ -121,5 +167,24 @@ public static void RegisterSyntaxNodeActionHonorExclusions<TLanguageKindEnum>(th
121167 } ,
122168 syntaxKinds ) ;
123169 }
170+
171+ private static class LanguageKindArrays < TLanguageKindEnum >
172+ where TLanguageKindEnum : struct
173+ {
174+ private static readonly ConcurrentDictionary < TLanguageKindEnum , ImmutableArray < TLanguageKindEnum > > Arrays =
175+ new ConcurrentDictionary < TLanguageKindEnum , ImmutableArray < TLanguageKindEnum > > ( ) ;
176+
177+ private static readonly Func < TLanguageKindEnum , ImmutableArray < TLanguageKindEnum > > CreateValueFactory = CreateValue ;
178+
179+ public static ImmutableArray < TLanguageKindEnum > GetOrCreateArray ( TLanguageKindEnum syntaxKind )
180+ {
181+ return Arrays . GetOrAdd ( syntaxKind , CreateValueFactory ) ;
182+ }
183+
184+ private static ImmutableArray < TLanguageKindEnum > CreateValue ( TLanguageKindEnum syntaxKind )
185+ {
186+ return ImmutableArray . Create ( syntaxKind ) ;
187+ }
188+ }
124189 }
125190}
0 commit comments