mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
* Add analyzers to detect some prototype misuse Detects people marking prototype as NetSerializable. Detects people creating new prototype instances themselves. * Update Robust.Analyzers/PrototypeNetSerializableAnalyzer.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> --------- Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
49 lines
1.8 KiB
C#
49 lines
1.8 KiB
C#
using System.Collections.Immutable;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.Diagnostics;
|
|
using Microsoft.CodeAnalysis.Operations;
|
|
using Robust.Roslyn.Shared;
|
|
|
|
namespace Robust.Analyzers;
|
|
|
|
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
|
public sealed class PrototypeInstantiationAnalyzer : DiagnosticAnalyzer
|
|
{
|
|
private const string PrototypeInterfaceType = "Robust.Shared.Prototypes.IPrototype";
|
|
|
|
public static readonly DiagnosticDescriptor Rule = new(
|
|
Diagnostics.IdPrototypeInstantiation,
|
|
"Do not instantiate prototypes directly",
|
|
"Do not instantiate prototypes directly. Prototypes should always be instantiated by the prototype manager.",
|
|
"Usage",
|
|
DiagnosticSeverity.Warning,
|
|
true);
|
|
|
|
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Rule];
|
|
|
|
public override void Initialize(AnalysisContext context)
|
|
{
|
|
context.EnableConcurrentExecution();
|
|
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
|
|
context.RegisterCompilationStartAction(static ctx =>
|
|
{
|
|
var prototypeInterface = ctx.Compilation.GetTypeByMetadataName(PrototypeInterfaceType);
|
|
if (prototypeInterface == null)
|
|
return;
|
|
|
|
ctx.RegisterOperationAction(symContext => Check(prototypeInterface, symContext), OperationKind.ObjectCreation);
|
|
});
|
|
}
|
|
|
|
private static void Check(INamedTypeSymbol prototypeInterface, OperationAnalysisContext ctx)
|
|
{
|
|
if (ctx.Operation is not IObjectCreationOperation { Type: { } resultType } creationOp)
|
|
return;
|
|
|
|
if (!TypeSymbolHelper.ImplementsInterface(resultType, prototypeInterface))
|
|
return;
|
|
|
|
ctx.ReportDiagnostic(Diagnostic.Create(Rule, creationOp.Syntax.GetLocation()));
|
|
}
|
|
}
|