mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
* Source gen reorganizations + component unpause generator. This commit (and subsequent commits) aims to clean up our Roslyn plugin (source gens + analyzers) stack to more sanely re-use common code I also built a new source-gen that automatically generates unpausing implementations for components, incrementing attributed TimeSpan field when unpaused. * Fix warnings in all Roslyn projects
46 lines
1.8 KiB
C#
46 lines
1.8 KiB
C#
using System.Collections.Immutable;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.Diagnostics;
|
|
using Microsoft.CodeAnalysis.Operations;
|
|
using Robust.Roslyn.Shared;
|
|
|
|
namespace Robust.Analyzers;
|
|
|
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
|
public sealed class TaskResultAnalyzer : DiagnosticAnalyzer
|
|
{
|
|
[SuppressMessage("ReSharper", "RS2008")]
|
|
private static readonly DiagnosticDescriptor ResultRule = new DiagnosticDescriptor(
|
|
Diagnostics.IdTaskResult,
|
|
"Risk of deadlock from accessing Task<T>.Result",
|
|
"Accessing Task<T>.Result is dangerous and can cause deadlocks in some contexts. If you understand how this works and are certain that you aren't causing a deadlock here, mute this error with #pragma.",
|
|
"Usage",
|
|
DiagnosticSeverity.Error,
|
|
true);
|
|
|
|
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
|
ImmutableArray.Create(ResultRule);
|
|
|
|
public override void Initialize(AnalysisContext context)
|
|
{
|
|
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
|
context.EnableConcurrentExecution();
|
|
context.RegisterOperationAction(Check, OperationKind.PropertyReference);
|
|
}
|
|
|
|
private static void Check(OperationAnalysisContext context)
|
|
{
|
|
var taskType = context.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
|
|
|
|
var operation = (IPropertyReferenceOperation) context.Operation;
|
|
var member = operation.Member;
|
|
|
|
if (member.Name == "Result" && taskType.Equals(member.ContainingType.ConstructedFrom, SymbolEqualityComparer.Default))
|
|
{
|
|
var diag = Diagnostic.Create(ResultRule, operation.Syntax.GetLocation());
|
|
context.ReportDiagnostic(diag);
|
|
}
|
|
}
|
|
}
|