Enable attributes on classes and methods to modify the AST before compiling

Topics: General
Nov 14, 2014 at 6:15 AM
Is it possible to allow customer attributes (inherited from a given base attribute) to change the AST of the class or the method to which that attribute is applied?

This allows the users to use Attributes to enable AOP and much more. Then the Nuget packages with attributes can be used as powerful language extension mechanisms.

e.g. 01

[Logging]
public void Method1()
{

}

Logging attribute should get an opportunity to modify the AST of Method 1 before compiling so that it can inject code to log entry, exit and any exceptions.

e.g. 02

[NotifyPropertyChanged]
public class Employee{

}

NotifyPropertyChanged attribute should get an opportunity to modify the AST of the Employee class before compiling, so that it can change its AST to implement the interface INotifyPropertyChanged automatically to notify changes in all its public properties.
Developer
Nov 14, 2014 at 2:46 PM
Roslyn doesn't have any support for anything like that today. We would welcome a spec (and perhaps prototype) of proposed language extensions to be considered.
Nov 14, 2014 at 8:42 PM
It wouldn't surprise me if a good 20% of all of the threads on these forums eventually get to meta-programming. It's one of those concepts that Roslyn brings to just outside of grasp and I think it would be massively exciting to discuss.

Personally I'd love to see some aspect* of the compiler that allows attributes to be written in such a way that when identified by the compiler it hands over the AST of the current item which the attribute can then transform. The attribute would then be stripped from the AST and not survive in the final assembly.

That description is grossly oversimplified, of course. For example, for an attribute like [NotifyPropertyChanged] applied to a property the aspect might have to amend the declaring type in order to make it implement INotifyPropertyChanged and add the appropriate members to satisfy that contract, if they don't already exist. I think that attributes may also have to be expanded to potentially permit use within methods, similar to how annotations can be applied to type assignments in Java. If these attributes are removed then it wouldn't require any CLR changes, although there may be value in supporting the retention of those attributes also perhaps as targeting the method and containing an IL offset.

Even where it is possible this does introduce the concept of injecting use code into the compilation phase which I think is a conversation on its own. Although maybe that could be avoided if a future Roslyn supported spitting the expression AST out to an intermediate file which another process could consume, amend and feed back to future Roslyn to generate the final assembly.

* Ha, see what I did there?
Developer
Nov 14, 2014 at 10:37 PM
We (at Sun Microsystems) designed and implemented "annotations" in Java (the equivalent to .NET's Attributes) to serve this purpose (among others), and shipped an "annotation processor" along with the set of tools. But annotation processors do not modify source code - rather they augment it with additional generated code. Allowing mutation of existing code and integrating this nicely with the IDE is hard. We have it on the list of things to think about for future revisions.