Skip to content

Conversation

@Tayrtahn
Copy link
Member

An issue that often comes up in content code reviews is that contributors will miss the opportunity to use a proxy method when one is available - for example, using EntityManager.TryGetComponent in an entity system, where they could use TryComp. These instances need to be caught and pointed out by reviewers, and addressed by PR authors, adding friction to the review process.

This PR allows proxy methods to be marked with a new ProxyFor attribute which indicates that they can and should be used by derived classes instead of specified methods of other classes.

ProxyForAttribute

The attribute looks like this:

[ProxyFor(typeof(EntityManager), nameof(EntityManager.GetComponent))]
protected T Comp<T>(EntityUid uid) where T : IComponent
{
    return EntityManager.GetComponent<T>(uid);
}

The first parameter indicates the Type containing the target method and is required. The second parameter is a string (please use nameof) with the name of the target method, and can be omitted if the proxy method name matches the target method name. As examples: TryComp does not match TryGetComponent so the parameter is needed, but GetEntityQuery matches GetEntityQuery so it can be omitted.

Warning

The analyzer will detect uses of the target method in classes where the proxy is available and raise a warning:
Screenshot 2025-06-15 at 10 12 03 PM

Fixer

Also included is a code fixer that can automatically replace the method with the proxy method.

Quick actions:

Screenshot 2025-06-15 at 10 12 27 PM

Result:

Screenshot 2025-06-15 at 10 12 39 PM

Self-checks

The analyzer also checks for proper use of the ProxyFor attribute.

Redundant method name

If the proxy method name matches the target method name and the attribute redundantly specifies the target method name, a warning is raised:
Screenshot 2025-06-16 at 10 57 30 AM
This also has a code fixer to remove the redundant parameter:
Screenshot 2025-06-16 at 10 57 39 AM

Target method check

The analyzer also checks that the target method exists and will raise an error if it does not:
Screenshot 2025-06-16 at 11 01 52 AM

This verifies that the target Type has a method with the target name (either manually set by parameter or automatically obtained from the proxy method name), the same type arguments as the proxy method, and accepting the same sequence of parameters as the proxy method.

Different parameters:

Screenshot 2025-06-16 at 11 12 40 AM

Application

This PR also goes ahead and marks all possible proxy methods in EntitySystem. The analyzer detects and flags 468 instances of those methods not being used when they could.

Tayrtahn added 6 commits June 16, 2025 13:15
… IComponent)"

This reverts commit a65ea71.

Might as well include this, since the file needs to be changed anyway.
Previously we searched with each method invocation.
This also lets us skip analysis on classes with no proxy methods available.
Copy link
Member Author

@Tayrtahn Tayrtahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two Three bugs to be fixed:

  • #6027 (comment) Analyzer needs to handle invocations within a delegate and not use variables from the outside scope.
  • #6027 (comment) Code fixer somehow ate a comment above a change. Need to prevent that.
  • #6027 (comment) Code fixer also ate a blank line.

@PJB3005 PJB3005 added A: Roslyn Components Roslyn analyzers, source generators, code fixes T: New Feature Type: New feature Priority: 3-Not Required labels Jun 20, 2025
@deltanedas
Copy link
Contributor

o lord
goidamerge
this peak

if (context.Node is not MethodDeclarationSyntax declarationSyntax)
return;

if (context.SemanticModel.GetDeclaredSymbol(declarationSyntax) is not { } methodSymbol)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad. Need to redo this to work with declaration operations instead so it doesn't need to get the semantic model for every declaration in the codebase.

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

Labels

A: Roslyn Components Roslyn analyzers, source generators, code fixes Priority: 3-Not Required T: New Feature Type: New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants