Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Advice Attribute with Generic not working on separate project #209

Open
moonheart opened this issue Aug 21, 2024 · 0 comments
Open

Comments

@moonheart
Copy link

reproduction repo: https://github.com/moonheart/MrAdvice_issue

Details

There are two advices in ClassLibrary1: GenericAdvice<TReturn> and NonGenericAdvice, when building finished, the NonGenericAdvice works as intended, but GenericAdvice<TReturn> only works in the same project as the advice .

public class GenericAdvice<TReturn>: Attribute, IMethodAdvice
{
    public void Advise(MethodAdviceContext context)
    {
        if (context.IsTargetMethodAsync)
        {
            context.ReturnValue = Task.FromResult((object)2);
        }
        else
        {
            context.ReturnValue = 2;
        }
    }
}

public class NonGenericAdvice: Attribute, IMethodAdvice
{
    public void Advise(MethodAdviceContext context)
    {
        if (context.IsTargetMethodAsync)
        {
            context.ReturnValue = Task.FromResult((object)2);
        }
        else
        {
            context.ReturnValue = 2;
        }
    }
}

Class in same project works:

namespace ClassLibrary1
{
  public class MyClass2
  {
    [GenericAdvice<List<int>>]
    public Task<int> Method1()
    {
      // ISSUE: method reference
      // ISSUE: method reference
      // ISSUE: method reference
      return (Task<int>) ⚡Invocation.ProceedAspect((object) this, __methodref (MyClass2.Method1), __methodref (MyClass2.Method1′), __methodref (MyClass2.Method1″));
    }

    [NonGenericAdvice]
    public Task<int> Method2()
    {
      // ISSUE: method reference
      // ISSUE: method reference
      // ISSUE: method reference
      return (Task<int>) ⚡Invocation.ProceedAspect((object) this, __methodref (MyClass2.Method2), __methodref (MyClass2.Method2′), __methodref (MyClass2.Method2″));
    }

    [ExecutionPoint]
    private Task<int> Method1()
    {
      // ISSUE: object of a compiler-generated type is created
      // ISSUE: variable of a compiler-generated type
      MyClass2.<Method1>d__0 stateMachine = new MyClass2.<Method1>d__0();
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>4__this = this;
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>1__state = -1;
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>t__builder.Start<MyClass2.<Method1>d__0>(ref stateMachine);
      // ISSUE: reference to a compiler-generated field
      return stateMachine.<>t__builder.Task;
    }

    private static object Method1″([In] object obj0, [In] object[] obj1)
    {
      return (object) ((MyClass2) obj0).Method1();
    }

    [ExecutionPoint]
    private Task<int> Method2′()
    {
      // ISSUE: object of a compiler-generated type is created
      // ISSUE: variable of a compiler-generated type
      MyClass2.<Method2>d__1 stateMachine = new MyClass2.<Method2>d__1();
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>4__this = this;
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>1__state = -1;
      // ISSUE: reference to a compiler-generated field
      stateMachine.<>t__builder.Start<MyClass2.<Method2>d__1>(ref stateMachine);
      // ISSUE: reference to a compiler-generated field
      return stateMachine.<>t__builder.Task;
    }

    private static object Method2″([In] object obj0, [In] object[] obj1)
    {
      return (object) ((MyClass2) obj0).Method2();
    }
  }
}

Class in different project not work:

public class MyClass1
{
  public async Task<int> Method1()
  {
    await Task.Delay(1); // <----- not weaved
    return 1;
  }

  [NonGenericAdvice]
  public Task<int> Method2()
  {
    // ISSUE: method reference
    // ISSUE: method reference
    // ISSUE: method reference
    return (Task<int>) ⚡Invocation.ProceedAspect((object) this, __methodref (MyClass1.Method2), __methodref (MyClass1.Method2′), __methodref (MyClass1.Method2″));
  }

  [ExecutionPoint]
  private Task<int> Method2()
  {
    // ISSUE: object of a compiler-generated type is created
    // ISSUE: variable of a compiler-generated type
    MyClass1.<Method2>d__1 stateMachine = new MyClass1.<Method2>d__1();
    // ISSUE: reference to a compiler-generated field
    stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
    // ISSUE: reference to a compiler-generated field
    stateMachine.<>4__this = this;
    // ISSUE: reference to a compiler-generated field
    stateMachine.<>1__state = -1;
    // ISSUE: reference to a compiler-generated field
    stateMachine.<>t__builder.Start<MyClass1.<Method2>d__1>(ref stateMachine);
    // ISSUE: reference to a compiler-generated field
    return stateMachine.<>t__builder.Task;
  }

  private static object Method2″([In] object obj0, [In] object[] obj1)
  {
    return (object) ((MyClass1) obj0).Method2();
  }
}
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

No branches or pull requests

1 participant