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

Proposal: Code interception via source attributes #8075

Closed
alrz opened this issue Jan 21, 2016 · 3 comments
Closed

Proposal: Code interception via source attributes #8075

alrz opened this issue Jan 21, 2016 · 3 comments

Comments

@alrz
Copy link
Member

alrz commented Jan 21, 2016

Currently, attributes are not aware of their targets whatsoever, but with source-only attributes (#6671), we can provide a nice API for interception and additional code generation in the same sense as #5561. This can be used to imitate a macro system but in a more managed fashion.

For example,

[[NPC]]
public partial class Person
{
  [[Property]]
  string Name { get; set; }
}

[AttributeUsage(AttributeTargets.Field)]
class PropertyAttribute : SourceAttribute {
  public override void Intercept(SymbolInjectionContext symbol) { ... }
}

[AttributeUsage(AttributeTargets.Class)]
class NPCAttribute : SourceAttribute {
  public override void Intercept(SymbolInjectionContext symbol) { ... }
}

Obviously executing Intercept happens early in the pipeline like #5561 code injectors.

The provided API should be able to add compilation units (related to #5561 and #5292).

Some scenarios that I'm expecting this to be really useful:

  • Implementing libraries like refit.
  • Code interception in general, e.g. implementing NPC.
  • Logging, mocking, exception handling, dependency injection, metaprogramming, AOP, etc.

Also I want to suggest the API provided be compatible with pattern-matching for easier examining the input (e.g. we can switch on the target symbol).

As a further consideration (like #7875), I would like to suggest preprocessor-like syntax for source-only attributes indicating that it gets evaluated earlier in the pipeline.

#[Mock]
extension IBar { } // #8127

Although, where and how to apply these attributes depend on the implementation details for each of those proposals.

@daveaglick
Copy link
Contributor

👍 - especially for using the same conventions and SymbolInjectionContext as #5561.

For this to be really useful though, I think superseded members (#5292) or some other mechanism for augmenting the intercepted code at specific locations (before the call, after the call) also needs to make it in. For example, if you want to intercept a method to add timing you'll need to create and fire a timer before invocation and then stop and log the cumulative time after invocation.

I'd also like to see a way to apply these attributes more globally: to every method in a given class, to every property in an assembly with a given name, to every method that starts with "Get", etc.

@alrz
Copy link
Member Author

alrz commented Jan 21, 2016

@daveaglick I specifically mentioned #5292 to be used for implementing these attributes. For applying these attribtues globally I can think of assembly attributes, for example, utilizing #1938:

#[assembly: GlobalInterception]

[AttributeUsage(AttributeTargets.Assembly)]
class GlobalInterceptionAttribute : SourceAttribute {
  public override void Intercept(SymbolInjectionContext symbol) {
    from @class in symbol.CompilationUnit.Types
    from member in @class.Members
    where member.Name.StartsWith("Get")
    do { ... }; // #1938
  }
}

or something like that. Similarly this can be used for an attribute applied to a class to intercept all members.

@gafter
Copy link
Member

gafter commented Mar 20, 2017

We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages.

@gafter gafter closed this as completed Mar 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants