Skip to content

Commit c67d808

Browse files
committed
Support multiple descriptors per analyzer
1 parent 8d5977d commit c67d808

1 file changed

Lines changed: 53 additions & 36 deletions

File tree

StyleCop.Analyzers.Status.Generator/SolutionReader.cs

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,26 @@ public async Task<ImmutableList<StyleCopDiagnostic>> GetDiagnosticsAsync()
144144

145145
codeFixStatus = this.HasCodeFix(id, classSymbol, out noCodeFixReason);
146146

147-
DiagnosticDescriptor descriptorInfo = this.GetDescriptor(classSymbol);
147+
IEnumerable<DiagnosticDescriptor> descriptorInfos = this.GetDescriptor(classSymbol);
148148

149-
string status = this.GetStatus(classSymbol, syntaxRoot, semanticModel);
150-
151-
var diagnostic = new StyleCopDiagnostic
149+
foreach (var descriptorInfo in descriptorInfos)
152150
{
153-
Id = descriptorInfo.Id,
154-
Category = descriptorInfo.Category,
155-
HasImplementation = hasImplementation,
156-
Status = status,
157-
Name = shortName,
158-
Title = descriptorInfo.Title.ToString(),
159-
HelpLink = descriptorInfo.HelpLinkUri,
160-
CodeFixStatus = codeFixStatus,
161-
NoCodeFixReason = noCodeFixReason
162-
};
163-
diagnostics.Add(diagnostic);
151+
string status = this.GetStatus(classSymbol, syntaxRoot, semanticModel, descriptorInfo);
152+
153+
var diagnostic = new StyleCopDiagnostic
154+
{
155+
Id = descriptorInfo.Id,
156+
Category = descriptorInfo.Category,
157+
HasImplementation = hasImplementation,
158+
Status = status,
159+
Name = shortName,
160+
Title = descriptorInfo.Title.ToString(),
161+
HelpLink = descriptorInfo.HelpLinkUri,
162+
CodeFixStatus = codeFixStatus,
163+
NoCodeFixReason = noCodeFixReason
164+
};
165+
diagnostics.Add(diagnostic);
166+
}
164167
}
165168

166169
return diagnostics.ToImmutable();
@@ -183,43 +186,57 @@ private static bool HasImplementation(SyntaxNode syntaxRoot)
183186
return hasImplementation;
184187
}
185188

186-
private string GetStatus(INamedTypeSymbol classSymbol, SyntaxNode root, SemanticModel model)
189+
private string GetStatus(INamedTypeSymbol classSymbol, SyntaxNode root, SemanticModel model, DiagnosticDescriptor descriptor)
187190
{
188191
// Some analyzers use multiple descriptors. We analyze the first one and hope that
189192
// thats enough.
190-
var members = classSymbol.GetMembers().FirstOrDefault(x => x.Name.Contains("Descriptor"));
191-
192-
VariableDeclaratorSyntax node = root.FindNode(members.Locations.FirstOrDefault().SourceSpan) as VariableDeclaratorSyntax;
193+
var members = classSymbol.GetMembers().Where(x => x.Name.Contains("Descriptor")).ToArray();
193194

194-
if (node == null)
195+
foreach (var member in members)
195196
{
196-
return "Unknown";
197-
}
197+
VariableDeclaratorSyntax node = root.FindNode(member.Locations.FirstOrDefault().SourceSpan) as VariableDeclaratorSyntax;
198198

199-
ObjectCreationExpressionSyntax initializer = node.Initializer.Value as ObjectCreationExpressionSyntax;
199+
if (node == null)
200+
{
201+
continue;
202+
}
200203

201-
// We use the fact that the only parameter that returns a boolean is the one we are interested in
202-
var enabledByDefaultParameter = from argument in initializer.ArgumentList.Arguments
203-
where model.GetTypeInfo(argument.Expression).Type == this.booleanType
204-
select argument.Expression;
205-
var parameter = enabledByDefaultParameter.FirstOrDefault();
206-
string parameterString = parameter.ToString();
207-
var analyzerConstantLength = "AnalyzerConstants.".Length;
204+
ObjectCreationExpressionSyntax initializer = node.Initializer.Value as ObjectCreationExpressionSyntax;
208205

209-
if (parameterString.Length < analyzerConstantLength)
210-
{
211-
return parameterString;
206+
var firstArgument = initializer.ArgumentList.Arguments[0];
207+
208+
string constantValue = (string)model.GetConstantValue(firstArgument.Expression).Value;
209+
210+
if (constantValue != descriptor.Id)
211+
{
212+
continue;
213+
}
214+
215+
// We use the fact that the only parameter that returns a boolean is the one we are interested in
216+
var enabledByDefaultParameter = from argument in initializer.ArgumentList.Arguments
217+
where model.GetTypeInfo(argument.Expression).Type == this.booleanType
218+
select argument.Expression;
219+
var parameter = enabledByDefaultParameter.FirstOrDefault();
220+
string parameterString = parameter.ToString();
221+
var analyzerConstantLength = "AnalyzerConstants.".Length;
222+
223+
if (parameterString.Length < analyzerConstantLength)
224+
{
225+
return parameterString;
226+
}
227+
228+
return parameter.ToString().Substring(analyzerConstantLength);
212229
}
213230

214-
return parameter.ToString().Substring(analyzerConstantLength);
231+
return "Unknown";
215232
}
216233

217-
private DiagnosticDescriptor GetDescriptor(INamedTypeSymbol classSymbol)
234+
private IEnumerable<DiagnosticDescriptor> GetDescriptor(INamedTypeSymbol classSymbol)
218235
{
219236
var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(this.assembly.GetType(classSymbol.ToString()));
220237

221238
// This currently only supports one diagnostic for each analyzer.
222-
return analyzer.SupportedDiagnostics.FirstOrDefault();
239+
return analyzer.SupportedDiagnostics;
223240
}
224241

225242
private CodeFixStatus HasCodeFix(string diagnosticId, INamedTypeSymbol classSymbol, out string noCodeFixReason)

0 commit comments

Comments
 (0)