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

Bug: LAMA0037: The aspect '' cannot be applied to the Type '' because <my reason> #194

Closed WhitWaldo closed 11 months ago

WhitWaldo commented 11 months ago

The eligibility rule doesn't appear to be working properly here - I'm attempting to validate that the user doesn't pass an empty or all-whitespace value to a string property on the aspect. Leaving the line in the eligibility builder shows this error when I attempt to preview the target type, but if I remove the eligibility line, the aspect works without issue.

public sealed class MyAttribute : TypeAspect
{
  private string _entityKeyPropertyName {get; init; }

  public MyAttribute(string entityKeyPropertyName)
  {
    _entityKeyPropertyName = entityKeyPropertyName;
  }

  public override void BuildEligibility(IEligibilityBuilder<INamedType> builder)
  {
    builder.MustSatisfy(_ => !string.IsNullOrWhiteSpace(_entityKeyIdPropertyName), _ => $"The entity key property name must be populated");
  }
}

Here's how the aspect is applied to the type:

[My("Id")]
internal class MyTestType
{
}

Regardless, I get the error bar reading: "Cannot preview the transformed code error LAMA0037: The aspect 'My' cannot be applied to the type 'MyTestType' because The entity key property name must be populated" even though it's clearly populated already.

Thank you!

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-33593.

WhitWaldo commented 11 months ago

Forgot to mention - running 2023.2.2-rc

svick commented 11 months ago

This is behaving as documented:

Your implementation of BuildEligibility must not reference any instance member of the class. This method is called on an instance obtained using FormatterServices.GetUninitializedObject, i.e., without invoking the class constructor.

I think in your case, you should emit a custom diagnostic instead of using eligibility.