postsharp / Metalama

Metalama is a Roslyn-based meta-programming framework. Use this repo to report bugs or ask questions.
164 stars 4 forks source link

Feature request: Allow BuildEligibility to refererence an instance member of the class #198

Closed WhitWaldo closed 11 months ago

WhitWaldo commented 11 months ago

Per the note in the docs, BuildEligibility must not reference any instance member of the class.

I'd like to request that this be changed to allow precisely this behavior. I have a TypeAspect that receives three arguments when the attribute is applied to a type. One of these three receives a Type of another record and I'd like to validate that it implements IComparable<>, IComparable and IEquatable<> before applying the aspect to the type.

It was suggested in this other issue that this should instead utilize a custom diagnostic, but this is not something that can or should be automatically fixed at compile time as it requires the decoration and possible implementation of these interfaces to the target type.

I believe this sort of check is better suited to the BuildEligibility or similar place than a diagnostic because in my case, my aspect will successfully compile, but the runtime code itself will result in dozens of errors because of generic constraints not being met by the type that was compiled into place, suggesting that this isn't something that just needs a diagnostic, but an outright blockage of aspect application if the type doesn't meet the requirements.

Thank you for the consideration!

PostSharpBot commented 11 months ago

Hello @WhitWaldo, thank you for submitting this issue. We will try to get back to you as soon as possible. Note to the PostSharp team, this ticket is being tracked in our dashboard under ID TP-33604.

WhitWaldo commented 11 months ago

This is no longer necessary as I was able to re-implement the aspect to use generic types and apply the constraints there instead.

WhitWaldo commented 11 months ago

Turns out that generic aspects are not yet supported, so re-opening this issue.

gfraiteur commented 11 months ago

Eligibility, by definition, cannot conceptually be of instance scope because it is evaluated before the instance is created. The main use case of eligibility is to determine which aspects must be offered to the code refactoring menu.

After you have an aspect instance, the standard way to report errors is to do it from BuildAspect through builder.Diagnostics.

However, if you want to use the Eligibility namespace because it is more convenient than the Diagnostics namespace, you can do so by calling builder.VerifyEligibility, as in this example:

 if ( !aspectBuilder.VerifyEligibility( EligibilityRuleFactory.CreateRule<IMethod>( x => x.MustNotBeStatic()))) 
  {
      return;
  }

The complete code is here

gfraiteur commented 11 months ago

Also note you can use builder.SkipAspect to block the application of the aspect.