using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Ariadne.Generator
{
///
/// Silences CS0164 ("label not referenced") on step labels in passages, and nowhere else.
///
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class StepLabelSuppressor : DiagnosticSuppressor
{
public static readonly SuppressionDescriptor UnreferencedStepLabel = new SuppressionDescriptor(
"ARIS0001", "CS0164", "In a passage, a label names a step for saves; nothing jumps to it.");
public override ImmutableArray SupportedSuppressions
{
get
{
return ImmutableArray.Create(UnreferencedStepLabel);
}
}
public override void ReportSuppressions(SuppressionAnalysisContext context)
{
var scripts = new Dictionary(SymbolEqualityComparer.Default);
foreach (Diagnostic diagnostic in context.ReportedDiagnostics)
{
SyntaxTree tree = diagnostic.Location.SourceTree;
if (tree == null)
{
continue;
}
SyntaxNode node = tree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan);
MethodDeclarationSyntax methodSyntax = node.FirstAncestorOrSelf();
if (methodSyntax == null)
{
continue;
}
var method = context.GetSemanticModel(tree).GetDeclaredSymbol(methodSyntax) as IMethodSymbol;
if (method == null)
{
continue;
}
ScriptClass script;
if (!scripts.TryGetValue(method.ContainingType, out script))
{
script = ScriptClass.Create(method.ContainingType, context.Compilation);
scripts[method.ContainingType] = script;
}
if (script != null && script.Passages.Contains(method))
{
context.ReportSuppression(Suppression.Create(UnreferencedStepLabel, diagnostic));
}
}
}
}
}