From 5e1935c310d305cac242ba1d1511073d4135a030 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Mon, 13 Jan 2025 05:52:31 +0100 Subject: [PATCH] Optimize ByRefEventAnalyzer According to a log, like 20 seconds of the build is spent in this analyzer. It now takes ~200ms. Hooray! --- Robust.Analyzers/ByRefEventAnalyzer.cs | 48 ++++++++++++++++---------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/Robust.Analyzers/ByRefEventAnalyzer.cs b/Robust.Analyzers/ByRefEventAnalyzer.cs index d5c2cad796a..9669892aff2 100644 --- a/Robust.Analyzers/ByRefEventAnalyzer.cs +++ b/Robust.Analyzers/ByRefEventAnalyzer.cs @@ -54,32 +54,44 @@ public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.EnableConcurrentExecution(); - context.RegisterOperationAction(CheckEventRaise, OperationKind.Invocation); + context.RegisterCompilationStartAction(compilationContext => + { + var raiseMethods = compilationContext.Compilation + .GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")? + .GetMembers() + .Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method) + .Cast(); + + var busRaiseMethods = compilationContext.Compilation + .GetTypeByMetadataName("Robust.Shared.GameObjects.EntityEventBus")? + .GetMembers() + .Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method) + .Cast(); + + if (raiseMethods == null) + return; + + if (busRaiseMethods != null) + raiseMethods = raiseMethods.Concat(busRaiseMethods); + + var raiseMethodsArray = raiseMethods.ToArray(); + + compilationContext.RegisterOperationAction( + ctx => CheckEventRaise(ctx, raiseMethodsArray), + OperationKind.Invocation); + }); } - private void CheckEventRaise(OperationAnalysisContext context) + private static void CheckEventRaise( + OperationAnalysisContext context, + IReadOnlyCollection raiseMethods) { if (context.Operation is not IInvocationOperation operation) return; - var raiseMethods = context.Compilation - .GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")? - .GetMembers() - .Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method) - .Cast(); - - var busRaiseMethods = context.Compilation - .GetTypeByMetadataName("Robust.Shared.GameObjects.EntityEventBus")? - .GetMembers() - .Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method) - .Cast(); - - if (raiseMethods == null) + if (!operation.TargetMethod.Name.Contains("RaiseLocalEvent")) return; - if (busRaiseMethods != null) - raiseMethods = raiseMethods.Concat(busRaiseMethods); - if (!raiseMethods.Any(m => m.Equals(operation.TargetMethod.OriginalDefinition, Default))) { // If you try to do this normally by concatenating like busRaiseMethods above