Skip to content

Add a Code Fix for converting EntitySystem event subscriptions to use attributes - #6909

Open
Tayrtahn wants to merge 33 commits into
space-wizards:masterfrom
Tayrtahn:analyzer/entitysystem-subscription-converter
Open

Add a Code Fix for converting EntitySystem event subscriptions to use attributes#6909
Tayrtahn wants to merge 33 commits into
space-wizards:masterfrom
Tayrtahn:analyzer/entitysystem-subscription-converter

Conversation

@Tayrtahn

@Tayrtahn Tayrtahn commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Adds an analyzer and code fix to detect instances of SubscribeXEvent method calls and replace them with the event subscription attributes added by #6227.

There are quite a few limitations on which instances can be replaced automatically, but this currently covers 4794 of them in engine and content, which I think is pretty good.

The analyzer detects SubscribeXEvent method invocations that are eligible for automatic conversion and marks them with an Info diagnostic:
Screenshot 2026-08-03 at 1 07 09 AM
(They show as ... in vscode, and I believe as a green squiggle in Rider)

Clicking Quick Fix or the lightbulb presents the option for the code fix:
Screenshot 2026-08-03 at 1 07 37 AM

The code fix:

  • Deletes the method invocation.
  • Adds the appropriate [SubscribeXEvent] attribute to the event handler method.
  • Adds partial to the class if it doesn't already have it.
  • Adds using Robust.Shared.Analyzers if needed.

This works even if the event handler is in a different file (for systems spread across multiple partial files).

If this deletes all the subscribe invocations from a method, it will leave behind an empty method or one that just calls its base. I investigated trying to automatically remove the method in those cases, but it wound up being quite complicated and I don't think it's worth trying to sort it all out.

There are a bunch of cases where the subscribe invocation can't be directly converted to use an attribute. The analyzer will not mark these cases; they will need manual conversion:

  • Subscriptions that are not at the top level of the containing method, such as those within an if statement, or a while loop. There's no way to conditionally apply the attribute, so these are skipped.
  • Subscriptions in classes that have any conditional preprocessor directives (#if, #else, etc). These are too complicated to try to parse and work out how to automatically convert, and there are (thankfully) very few of them.
  • Event handlers that aren't explicitly defined class methods, such as subscriptions using lambda expressions (SubscribeLocalEvent<MyComp, MyEvent>((u, c, ref _) => MyMethod(u, c, e));)
  • Subscriptions with before and after parameters are currently unsupported by the attributes, so the fixer ignores them. If support is added, I'll probably update this to work with it. Support added! Code fix updated!
  • Subscriptions using a generic type parameter: SubscribeLocalEvent<TComp, MyEvent>(MyMethod);
  • Event handlers that are generic methods: private MyMethod<T>(Entity<MyComp> entity, ref T args) { }
  • Event handlers with abstract event types: private MyMethod(Entity<MyComp> entity, ref BaseMyEvent args) { } (where BaseMyEvent is an abstract type)

With these restrictions, I was able to blindly run Fix All on the full engine+content solution and produce code that compiles correctly. If downstream content runs into any additional edge cases, please let me know!

Tayrtahn added 28 commits July 7, 2026 16:42
No longer confused by other methods with the same name
Needed so that Robust.Shared.Analyzers is available to autogenerated code.
This allows the analyzer/fixer to work on partial classes with InitializeSubsystem methods.
Saves us from needing to get the semantic model when registering the fix.
@Tayrtahn
Tayrtahn requested a review from DrSmugleaf as a code owner August 3, 2026 14:30
@Winkarst-cpu

Copy link
Copy Markdown
Contributor

#6904 was merged. Can you add support for it?

@Tayrtahn

Tayrtahn commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Support added for conversions with before and after!

Input:
Screenshot 2026-08-05 at 11 22 26 PM
Converted:
Screenshot 2026-08-05 at 11 22 50 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants